package com.quanxiaoha.xiaohashu.auth.service.impl;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.google.common.base.Preconditions;
import com.quanxiaoha.framework.common.exception.BizException;
import com.quanxiaoha.framework.common.response.Response;
import com.quanxiaoha.framework.common.util.JsonUtils;
import com.quanxiaoha.xiaohashu.auth.constant.RedisKeyConstants;
import com.quanxiaoha.xiaohashu.auth.enums.LoginTypeEnum;
import com.quanxiaoha.xiaohashu.auth.enums.ResponseCodeEnum;
import com.quanxiaoha.framework.biz.context.holder.LoginUserContextHolder;
import com.quanxiaoha.xiaohashu.auth.model.vo.user.UpdatePasswordReqVO;
import com.quanxiaoha.xiaohashu.auth.model.vo.user.UserLoginReqVO;
import com.quanxiaoha.xiaohashu.auth.rpc.UserRpcService;
import com.quanxiaoha.xiaohashu.auth.service.AuthService;
import com.quanxiaoha.xiaohashu.user.dto.resp.FindUserByPhoneRspDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
@Slf4j
public class AuthServiceImpl implements AuthService {
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource(name = "taskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private UserRpcService userRpcService;

    @Override
    public Response<String> loginAndRegister(UserLoginReqVO userLoginReqVO) {
        String phone = userLoginReqVO.getPhone();
        Integer type = userLoginReqVO.getType();
        LoginTypeEnum loginTypeEnum = LoginTypeEnum.valueOf(type);
        // 登录类型错误
        if (Objects.isNull(loginTypeEnum)) {
            throw new BizException(ResponseCodeEnum.LOGIN_TYPE_ERROR);
        }
        Long userId = null;
        switch(loginTypeEnum){
            case VERIFICATION_CODE://验证码登录
                String verificationCode = userLoginReqVO.getCode();

                //验证验证码是否为空
                Preconditions.checkArgument(StringUtils.isNotBlank(verificationCode), "验证码不能为空");
                //构建验证码Redis key
                String key = RedisKeyConstants.buildVerificationCodeKey(phone);
                //查询存储在redis中的验证码
                String sentCode = (String)redisTemplate.opsForValue().get(key);
                
                if(!StringUtils.equals(verificationCode,sentCode)){
                    throw new BizException(ResponseCodeEnum.VERIFICATION_CODE_ERROR);
                }

                FindUserByPhoneRspDTO userByPhone = userRpcService.findUserByPhone(phone);
                log.info("用户是否注册，phone:{},userDO:{}",phone, JsonUtils.toJsonString(userByPhone));
                //判断是否注册
                if(Objects.isNull(userByPhone)){
                    //如果没注册，自动注册
                    userId = userRpcService.registerUser(phone);
                    //TODO 用户注册
                }else{
                    userId = userByPhone.getId();
                }
                break;
            case PASSWORD:
                String password = userLoginReqVO.getPassword();
                FindUserByPhoneRspDTO userByPhone1 = userRpcService.findUserByPhone(phone);
                if(Objects.isNull(userByPhone1)){
                    throw new BizException(ResponseCodeEnum.USER_NOT_FOUND);
                }
                String encodePassword = userByPhone1.getPassword();
                boolean matches = passwordEncoder.matches(password, encodePassword);
                if(!matches){
                    throw new BizException(ResponseCodeEnum.PHONE_OR_PASSWORD_ERROR);
                }
                userId = userByPhone1.getId();



                //TODO

                break ;
            default:
                break;


        }
        //SaToken登录用户，入参为用户id
        StpUtil.login(userId);
        //获取登录令牌
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        //返回token令牌
        return Response.success(tokenInfo.tokenValue);

    }

    @Override
    public Response<?> logout() {
        //退出登录
        Long userId = LoginUserContextHolder.getUserId();
        log.info("==> 用户退出登录, userId: {}", userId);

//        threadPoolTaskExecutor.submit(() -> {
//            Long userId2 = LoginUserContextHolder.getUserId();
//            log.info("==> 异步线程中获取 userId: {}", userId2);
//        });
        StpUtil.logout(userId);
        return Response.success();
    }

    @Override
    public Response<?> updatePassword(UpdatePasswordReqVO updatePasswordReqVO) {
        String newPassword = updatePasswordReqVO.getNewPassword();
        String encodePassword = passwordEncoder.encode(newPassword);

        userRpcService.updatePassword(encodePassword);

        return Response.success();


    }
}
